In [1]:
def test_board():
    """
    >>> build_board(1, 1, 1)
    [['B']]
    >>> build_board(1,3, 3)
    [['B', 'B', 'B']]
    >>> build_board(3, 1, 0, non_bomb_character = "X")
    [['X'], ['X'], ['X']]
    >>> build_board(3, 6, 0, non_bomb_character = "y")
    [['y', 'y', 'y', 'y', 'y', 'y'], ['y', 'y', 'y', 'y', 'y', 'y'], ['y', 'y', 'y', 'y', 'y', 'y']]
    >>> build_board(3, 3, 9)
    [['B', 'B', 'B'], ['B', 'B', 'B'], ['B', 'B', 'B']]
    >>> build_board(3, 3, 300)
    [['B', 'B', 'B'], ['B', 'B', 'B'], ['B', 'B', 'B']]
    >>> build_board(4, 3, 0)
    [['-', '-', '-'], ['-', '-', '-'], ['-', '-', '-'], ['-', '-', '-']]
    """
    import doctest
    doctest.testmod()
    print("TESTING COMPLETE... if you see nothing, (other than this message) that means all tests passed.")

Possible Solution


In [2]:
import random


def build_board(num_rows, num_cols, bomb_count=0, non_bomb_character="-"):
    board_temp = ["B"] * bomb_count + [non_bomb_character] * (num_rows * num_cols - bomb_count)

    if bomb_count:
        random.shuffle(board_temp)

    board = []
    for i in range(0, num_rows*num_cols, num_cols):
        board.append(board_temp[i:i+num_cols])
    return board

# Runing the tests...
test_board()
# Note if you recieve an error message saying test_board not found 
# try hitting the run button on the test_board cell and try again.


TESTING COMPLETE... if you see nothing, (other than this message) that means all tests passed.

Explaining my code

Okay guys, my code is a bit complicated to understand at first glance, but I'm going to talk you through it.

board_temp = ["B"] * bomb_count + [non_bomb_character] * (row * col-bomb_count)

So this line of code looks like a monster, but actually once you think about it is not so difficult to understand. Basically we start by making a list containing "B" characters, the number of "B"'s we add to the list is dependant on the number of bombs the board is supposed to have (which is given by the bomb count argument).


In [9]:
bomb_count = 3
["B"] * bomb_count


Out[9]:
['B', 'B', 'B']

The next step is to multiply the row by the col to get the total number of squares our board should have. We subtract the bomb_count from this figure because we have already added those to the board and we do not wish to 'double count'.

For example, if bomb_count is 10 and our board is 10x10 then we want to add 90 non-bomb characters to the list (10*10 - 10 = 90). The result is a list of length 100, 10 of which are bombs.


In [10]:
row = 2
col = 2 
b_count = 1

part_one_of_list = ["B"] * b_count
part_two_of_list = ["-"] * (row * col-b_count)

our_list = part_one_of_list + part_two_of_list

print(our_list)  # --> 2x2 grid with 1 bomb.


['B', '-', '-', '-']

The next two lines of code are:

    if bomb_count:
        random.shuffle(board_temp)

So this code shuffles the list (but only if bombs >= 1), we take a list with all the bombs at the start and we jumble them around.

 board = []
 for i in range(0, row*col, col ):
    board.append(board_temp[i : i+col])

So this is the most complex part of my function, what are we doing here?

We have a range function, which starts at 0, ends at row * col and has a step of size col. Next up, we use those values to slice the temp_board we made earlier. In effect this is creating a 'moving window', and this gives us our board with the correct dimensions.

Lets try to visualise what is happening here by running it a few times with print statement:


In [9]:
## Create a 1d board
board_temp = [str(i).zfill(2) for i in range(1,21)]
print(board_temp)


['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20']

In [10]:
row = 5
col = 4

# print board with dims (5, 4)
for i in range(0, row*col, col ):
    print(board_temp[i : i+col])


['01', '02', '03', '04']
['05', '06', '07', '08']
['09', '10', '11', '12']
['13', '14', '15', '16']
['17', '18', '19', '20']

In [17]:
row = 3
col = 9

# print board with dims (3, 9)
for i in range(0, row*col, col ):
    print(board_temp[i : i+col])


['01', '02', '03', '04', '05', '06', '07', '08', '09']
['10', '11', '12', '13', '14', '15', '16', '17', '18']
['19', '20']

In [14]:
row = 6
col = 2

# print board with dims (6, 2)
for i in range(0, row*col, col ):
    print(board_temp[i : i+col])


['01', '02']
['03', '04']
['05', '06']
['07', '08']
['09', '10']
['11', '12']

In the above demonstration the board consists of 20 squares. As we If change the row/col dimensions of the board you should begin to see how the code works.